package com.demo2do.fms.admin.service.supplier.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.page.Page;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.fms.admin.dao.supplier.SupplierDao;
import com.demo2do.fms.admin.dao.supplier.SupplierProfileDao;
import com.demo2do.fms.admin.dao.supplier.SupplierRelationDao;
import com.demo2do.fms.admin.entity.search.supplier.SupplierAuditSearch;
import com.demo2do.fms.admin.service.supplier.SupplierAuditService;
import com.demo2do.fms.entity.supplier.common.AuditStatus;
import com.demo2do.fms.entity.supplier.common.Supplier;
import com.demo2do.fms.entity.supplier.common.SupplierCertificate;
import com.demo2do.fms.entity.supplier.common.SupplierEvent;
import com.demo2do.fms.entity.supplier.common.SupplierEventType;
import com.demo2do.fms.entity.supplier.common.SupplierInfo;
import com.demo2do.fms.entity.supplier.common.SupplierModifiedVersion;
import com.demo2do.fms.entity.supplier.common.SupplierRecommendation;
import com.demo2do.fms.entity.supplier.common.SyncStatus;
import com.demo2do.fms.entity.supplier.common.Type;
import com.demo2do.fms.entity.supplier.trans.TransSupplier;
import com.demo2do.fms.entity.supplier.ware.WareSupplier;
import com.demo2do.fms.entity.vehicle.ModifiedStatus;

/**
 * 
 * @author mohanlan
 *
 */
@Service("supplierAuditService")
public class SupplierAuditServiceImpl implements SupplierAuditService {
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Dao
    private SupplierDao supplierDao;
    
    @Dao
    private SupplierRelationDao supplierRelationDao;
    
    @Dao
    private SupplierProfileDao supplierProfileDao;
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#countSupplierByStatus(com.demo2do.fms.entity.supplier.common.AuditStatus[])
     */
    public int countSupplierByStatus(AuditStatus[] status) {
        return supplierDao.countSupplierByStatus(status);
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#countSupplierByStatus(com.demo2do.fms.entity.supplier.common.AuditStatus, java.lang.String)
     */
    public int countSupplierByStatus(AuditStatus status, String syncStatus) {
        int count = 0;
        if(status.isAuditing() && syncStatus == null) {
            count = supplierDao.countSupplierByStatus(new AuditStatus[]{status});
        } else if (status.isQualified() && syncStatus != null) {
            count = supplierDao.countSupplierByStatus(new AuditStatus[]{AuditStatus.QUALIFIED, AuditStatus.ONE_LEVEL_RECTIFY, AuditStatus.TWO_LEVEL_RECTIFY, AuditStatus.UNITE_RECTIFY}, SyncStatus.aliasOf(syncStatus));
        }
        return count;
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#countSupplierByStatus(com.demo2do.fms.entity.supplier.common.AuditStatus[], java.lang.Long)
     */
    public int countSupplierByStatus(AuditStatus[] status, Supplier parent) {
        return supplierRelationDao.countSupplierByStatus(parent, status);
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#listSupplierByStatus(com.demo2do.fms.entity.supplier.common.AuditStatus[], com.demo2do.core.entity.page.Page)
     */
    public List<Supplier> listSupplierByStatus(AuditStatus[] status, Page page) {
        List<Supplier> suppliers = supplierDao.listSupplierByPage(status, page.getBeginIndex(), page.getEveryPage());
        page.calculate();
        return suppliers;
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#listSupplierByStatus(com.demo2do.fms.entity.supplier.common.AuditStatus, java.lang.String, com.demo2do.core.entity.page.Page)
     */
    public List<Supplier> listSupplierByStatus(AuditStatus status, String syncStatus, Page page) {
    	
        List<Supplier> suppliers = new ArrayList<Supplier>();
        if(status.isAuditing() && syncStatus == null) {
            suppliers = supplierDao.listSupplierByPage(new AuditStatus[]{status}, page.getBeginIndex(), page.getEveryPage());
        } else if (status.isQualified() && syncStatus != null) {
            //suppliers = supplierDao.listSupplierByPage(status, SyncStatus.aliasOf(syncStatus), page.getBeginIndex(), page.getEveryPage());
            suppliers = supplierDao.listSupplierByPage(new AuditStatus[]{AuditStatus.QUALIFIED, AuditStatus.ONE_LEVEL_RECTIFY, AuditStatus.TWO_LEVEL_RECTIFY, AuditStatus.UNITE_RECTIFY}, SyncStatus.aliasOf(syncStatus), page.getBeginIndex(), page.getEveryPage());
        }
        
        page.calculate();
        return suppliers;
        
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#listSupplierByStatus(com.demo2do.fms.entity.supplier.common.AuditStatus[], java.lang.Long, com.demo2do.core.entity.page.Page)
     */
    public List<Supplier> listSupplierByStatus(AuditStatus[] status, Supplier parent, Page page) {
        List<Supplier> suppliers = supplierRelationDao.listSupplierByPage(parent, status, page.getBeginIndex(), page.getEveryPage());
        page.calculate();
        return suppliers;
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#searchSupplier(com.demo2do.fms.admin.entity.search.SupplierAuditSearch, com.demo2do.core.entity.page.Page)
     */
    @SuppressWarnings("unchecked")
    public List<Supplier> searchSupplier(SupplierAuditSearch search, Page page) {
        String sentence = search.buildSentenceTemplate();
        Map<String, Object> params = search.buildParameters();
        List<Supplier> result = genericDaoSupport.searchForList(sentence, params, page.getBeginIndex(), page.getEveryPage());
        page.calculate();
        return result;
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#introduceSupplier(com.demo2do.fms.entity.supplier.common.Supplier, java.lang.Long)
     */
    public void introduce(Supplier supplier, Long operator) {
        
        String validMessage = this.validateIntroduce(supplier);
        if(StringUtils.isNotBlank(validMessage)) {
            throw new BusinessException(validMessage);
        }
        
        // 1. change supplier status
        genericDaoSupport.update(supplier.editStatus(AuditStatus.AUDITING, operator));
        
        // 2. save supplier_event
        genericDaoSupport.save(new SupplierEvent(supplier, SupplierEventType.INTRODUCE, operator));
        
    }
    
    /**
     * 
     * @param supplier
     * @return
     */
    private String validateIntroduce(Supplier supplier) {
        
        if(StringUtils.isNotBlank(supplier.inValidMessage())) {
            return supplier.inValidMessage();
        }
        
        SupplierInfo supplierInfo = supplierProfileDao.getSupplierInfo(supplier.getId());
        if (supplierInfo == null) {
            return "服务供方基本信息不存在";
        } else if (StringUtils.isNotBlank(supplierInfo.inValidMessage())) {
            return supplierInfo.inValidMessage();
        }
        
        SupplierCertificate certificate = supplierProfileDao.getSupplierCertificate(supplier.getId());
        if (certificate == null) {
            return "服务供方业务信息不存在";
        } else if (StringUtils.isNotBlank(certificate.inValidMessage())) {
            return certificate.inValidMessage();
        }
        
        // Load transSupplier or waveSupplier and valid
        if(supplier.getType().equals(Type.MOTOR)) {
            TransSupplier transSupplier = supplierProfileDao.getTransSupplier(supplier.getId());
            if (transSupplier == null) {
                return "运输供方信息不存在";
            } else if (StringUtils.isNotBlank(transSupplier.inValidMessage())) {
                return transSupplier.inValidMessage();
            }
            
        } else if(supplier.getType().equals(Type.STORAGE)){
            WareSupplier wareSupplier = supplierProfileDao.getWareSupplier(supplier.getId());
            if (wareSupplier == null) {
                return "仓储供方信息不存在";
            } else if (StringUtils.isNotBlank(wareSupplier.inValidMessage())) {
                return wareSupplier.inValidMessage();
            }
        }
        
        // Load supplierRecommadaztion and valid;
        SupplierRecommendation recommendation = supplierProfileDao.getSupplierRecommendation(supplier.getId());
        if (recommendation == null) {
            return "申请人上传各类文件资料不存在";
        } else if (StringUtils.isNotBlank(recommendation.inValidMessage())) {
            return recommendation.inValidMessage();
        }
        
        return null;
        
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#onAdopt(com.demo2do.fms.entity.supplier.common.Supplier, java.lang.Long)
     */
    public void onAdopt(Supplier supplier, Long operator) {
        
        String message = supplier.couldAdopt();
        if (StringUtils.isNotBlank(message)) {
            throw BusinessException.newInstance("500", message);
        }
        
        // 1. change supplier status
        genericDaoSupport.update(supplier.editStatus(AuditStatus.QUALIFIED, operator));
        
        // 2.add new supplier_event
        genericDaoSupport.save(new SupplierEvent(supplier,SupplierEventType.INTRODUCE_PASSED, operator));
        
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#changingAdopt(com.demo2do.fms.entity.supplier.common.Supplier, java.lang.Long)
     */
    public void changingAdopt(Supplier supplier, Long operator) {
        
        // 获取最新版本的变更申报信息
        SupplierModifiedVersion version = supplierDao.loadModifiedVersion(supplier.getId(), ModifiedStatus.AUDITING);
        
        // 更新公司信息
        genericDaoSupport.update(supplier.change(version, operator));
        
        // update supplierInfo
        SupplierInfo supplierInfo = genericDaoSupport.load(SupplierInfo.class, version.getSupplierInfoId());
        genericDaoSupport.update(supplierInfo.change(version, operator));
        
        // 更新这一公司的所有version为合格状态
        supplierDao.updateModifiedVersion(ModifiedStatus.QUALIFIED, supplier.getId(), ModifiedStatus.AUDITING);
        
        // save supplier_event
        genericDaoSupport.save(new SupplierEvent(supplier,SupplierEventType.CHANGE_PASSED, operator));
        
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#onIntroduceAudit(com.demo2do.fms.entity.supplier.common.Supplier, java.lang.String, java.lang.Long)
     */
    public void introduceReject(Supplier supplier, String comment, Long operator) {
        
        // 1. change supplier status
        genericDaoSupport.update(supplier.editStatus(AuditStatus.REJECTED, operator));
        
        // 2.add new supplier_event
        SupplierEvent supplierEvent = new SupplierEvent(supplier,SupplierEventType.INTRODUCE_REJECTED, operator);
        genericDaoSupport.save(supplierEvent.editReason(comment));
        
    }
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.fms.admin.service.supplier.SupplierAuditService#changingReject(com.demo2do.fms.entity.supplier.common.Supplier, java.lang.String, java.lang.Long)
     */
    public void changingReject(Supplier supplier, String comment, Long operator) {
        
        // 1. change supplier status
        genericDaoSupport.update(supplier.editSyncStatus(SyncStatus.REJECTED, operator));
        
        // 2.update supplier version status
        supplierDao.updateModifiedVersion(ModifiedStatus.REJECTED, supplier.getId(), ModifiedStatus.AUDITING);
        
        // 3.add new supplier_event
        SupplierEvent supplierEvent = new SupplierEvent(supplier,SupplierEventType.CHANGE_REJECTED, operator);
        genericDaoSupport.save(supplierEvent.editReason(comment));
        
    }
}
